#include "s3c2440_gpio.h"
void* GpioBase = NULL;
void* CLKBASE = NULL;
int fd=-1;
int gpio_init()
{
	fd = open("/dev/mem", O_RDWR | O_SYNC);
	if(fd<0)
	{
		return ERR_FILEERR;
	}
	// CLK寄存器内存映射
	CLKBASE = mmap(NULL, (CLKREG_EndAddr-CLKREG_StartAddr), PROT_READ|PROT_WRITE, MAP_SHARED,fd, CLKREG_StartAddr & PAGE_MASK);
	if(CLKBASE == NULL || CLKBASE == MAP_FAILED)
        {
            gpio_exit();
            return ERR_FMAPERR;
        }
	GpioBase = mmap(NULL, (GPIO_EndAddr-GPIO_StartAddr), PROT_READ|PROT_WRITE, MAP_SHARED,fd, GPIO_StartAddr & PAGE_MASK);
	if(GpioBase == NULL || GpioBase == MAP_FAILED)
	{
            gpio_exit();
            return ERR_GMAPERR;
	}
	// enable PLCK(50Mhz) GPIO Block */
	REG((unsigned int)CLKBASE+CLKCON) |=0x2000;
	return 0;
}

void gpio_exit(){
	if(GpioBase != NULL)
	{
		munmap(GpioBase,(GPIO_EndAddr-GPIO_StartAddr));
		GpioBase = NULL;
	}
	if(CLKBASE != NULL)
	{
		munmap(CLKBASE,(CLKREG_EndAddr-CLKREG_StartAddr));
		CLKBASE = NULL;
	}
	if(fd != -1)
	{
		close(fd);
		fd = -1;
	}
	return;
}

void gpio_ioctl(unsigned int blank, int num, int type)
{
	unsigned int tmp=0;
    tmp=REG((unsigned int)GpioBase +blank);
    if(blank>0)
    {
        type &= 3;
        tmp &= ~(3<<(num*2));		/*used for GPIO Bank B-J, which use the 2 bits Mask*/
        tmp|= (type<<num*2);
    }
    else
    {
        type &= 1;
        tmp &= ~(1<<num);		/*used for GPIO Bank A, which use the 1 bit Mask*/
        tmp|= (type<<num);
    }

    REG((unsigned int)GpioBase +blank)=tmp;
}

unsigned int gpio_read(unsigned int blank, int num)
{
	unsigned int tmp=0;
    tmp=REG((unsigned int)GpioBase +blank + 4);
    tmp &= (1<<num);
    return tmp?1:0;
}

void gpio_write(unsigned int blank, int num, int status)
{
	unsigned int tmp=0;
    tmp=REG((unsigned int)GpioBase +blank + 4);
    tmp &= ~(1<<num);
    tmp |= (!!status<<num);
    REG((unsigned int)GpioBase +blank + 4)=tmp;
}


